﻿// <copyright file="MainViewModelTests.cs" company="Mooville">
//   Copyright © 2010 Roger Deetz. All rights reserved.
// </copyright>

namespace Mooville.QUno.ViewModel.Tests
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Mooville.QUno.Model;
    using Mooville.QUno.Testing.Mocks;
    using Mooville.QUno.ViewModel;

    [TestClass]
    public class MainViewModelTests
    {
        [TestMethod]
        public void Constructor_ShouldNotThrow()
        {
            MainViewModel target = new MainViewModel();
            Assert.IsNotNull(target);

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void Constructor_GivenNullSerializer_ShouldThrow()
        {
            MainViewModel target = new MainViewModel(null);

            return;
        }

        [TestMethod]
        public void AfterConstructor_Title_ShouldBeNull()
        {
            MainViewModel target = new MainViewModel();
            Assert.IsNull(target.Title);

            return;
        }

        [TestMethod]
        public void AfterConstructor_ComputerPlayers_ShouldBeEmpty()
        {
            MainViewModel target = new MainViewModel();
            Assert.IsTrue(target.ComputerPlayers.IsEmpty);

            return;
        }

        [TestMethod]
        public void AfterConstructor_Log_ShouldBeEmpty()
        {
            MainViewModel target = new MainViewModel();
            Assert.IsTrue(target.Log.IsEmpty);

            return;
        }

        [TestMethod]
        public void AfterConstructor_IsGameInProgress_ShouldBeFalse()
        {
            MainViewModel target = new MainViewModel();
            Assert.IsFalse(target.IsGameInProgress);

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void StartGame_GivenNull_ShouldThrow()
        {
            MainViewModel target = new MainViewModel();
            target.StartGame(null);

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void StartGame_GivenEmptyList_ShouldThrow()
        {
            List<Player> players = new List<Player>();
            MainViewModel target = new MainViewModel();
            target.StartGame(players);

            return;
        }

        [TestMethod]
        public void StartGame_GivenPlayers_ShouldNotThrow()
        {
            List<Player> players = new List<Player>();
            players.Add(new Player() { Name = "Roger", IsHuman = false });
            players.Add(new Player() { Name = "Livy", IsHuman = false });
            players.Add(new Player() { Name = "Lucy", IsHuman = false });
            players.Add(new Player() { Name = "Lainey", IsHuman = false });

            MainViewModel target = new MainViewModel();
            target.StartGame(players);
            Assert.IsNotNull(target);

            return;
        }

        [TestMethod]
        public void CanPlayCard_GivenNull_ShouldReturnFalse()
        {
            MainViewModel target = new MainViewModel();
            bool result = target.CanPlayCard(null);
            Assert.IsFalse(result);

            return;
        }

        [TestMethod]
        public void CanPlayCard_GivenCardWithNoGame_ShouldReturnFalse()
        {
            MainViewModel target = new MainViewModel();
            bool result = target.CanPlayCard(new Card(Color.Red, Value.Five));
            Assert.IsFalse(result);

            return;
        }

        [TestMethod]
        public void CanPlayCard_GivenCardWithGame_ShouldNotThrow()
        {
            List<Player> players = new List<Player>();
            players.Add(new Player() { Name = "Roger", IsHuman = false });
            players.Add(new Player() { Name = "Livy", IsHuman = false });
            players.Add(new Player() { Name = "Lucy", IsHuman = false });
            players.Add(new Player() { Name = "Lainey", IsHuman = false });

            MainViewModel target = new MainViewModel();
            target.StartGame(players);
            bool result = target.CanPlayCard(new Card(Color.Red, Value.Five));
            Assert.IsInstanceOfType(result, typeof(bool));

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void PlayCard_GivenNull_ShouldThrow()
        {
            MainViewModel target = new MainViewModel();
            target.PlayCard(null);

            return;
        }

        [TestMethod]
        public void PlayCard_WithNoGameInProgressGivenCard_ShouldNotThrow()
        {
            MainViewModel target = new MainViewModel();
            target.PlayCard(new Card(Color.Red, Value.Five));

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void PlayCardWild_GivenNullCard_ShouldThrow()
        {
            MainViewModel target = new MainViewModel();
            target.PlayCard(null, Color.Red);

            return;
        }

        [TestMethod]
        public void PlayCardWild_WithNoGameInProgressGivenCard_ShouldNotThrow()
        {
            MainViewModel target = new MainViewModel();
            target.PlayCard(new Card(Color.Wild, Value.Wild), Color.Red);

            return;
        }

        [TestMethod]
        public void DrawCard_WithNoGameInProgress_ShouldNotThrow()
        {
            MainViewModel target = new MainViewModel();
            target.DrawCard();

            return;
        }

        [TestMethod]
        public void TakeTurn_WithNoGameInProgress_ShouldNotThrow()
        {
            MainViewModel target = new MainViewModel();
            target.TakeTurn();

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void OpenGame_GivenNull_ShouldThrow()
        {
            MainViewModel target = new MainViewModel(new TestGameSerializer());
            target.OpenGame(null);

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void OpenGame_GivenEmptyString_ShouldThrow()
        {
            MainViewModel target = new MainViewModel(new TestGameSerializer());
            target.OpenGame(String.Empty);

            return;
        }

        [TestMethod]
        public void OpenGame_GivenFileName_ShouldRaisePropertyChanged()
        {
            bool fired = false;
            MainViewModel target = new MainViewModel(new TestGameSerializer());
            target.PropertyChanged += new PropertyChangedEventHandler((sender, e) => { fired = true; });
            target.OpenGame(@"C:\game.quno");
            Assert.IsTrue(fired);

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void SaveGame_GivenNull_ShouldThrow()
        {
            MainViewModel target = new MainViewModel(new TestGameSerializer());
            target.SaveGame(null);

            return;
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void SaveGame_GivenString_ShouldThrow()
        {
            MainViewModel target = new MainViewModel(new TestGameSerializer());
            target.SaveGame(String.Empty);

            return;
        }

        [TestMethod]
        public void SaveGame_WithNoGameInProgress_ShouldNotThrow()
        {
            MainViewModel target = new MainViewModel();
            target.SaveGame(@"C:\game.quno");

            return;
        }
    }
}
